let answer = fun x -> if x then 2 else 4;;

let rec split (lst: ('a * 'b) list) = 
    match lst with
      [] -> [], []
      | (a,b)::xs -> 
	    let xa, xb = split xs in
		a::xa, b::xb
;;

(* Q: can I fall off the pattern matching like in F# *)		
let rec combine (l1: 'a list) (l2: 'b list) = 
    match l1, l2 with
	[], [] -> []
      |	[], y::ys -> raise (Invalid_argument "not euqal length")
      | x::xs, [] -> raise (Invalid_argument "not euqal length")
      | x::xs, y::ys ->
	  (x,y)::(combine xs ys)
;;

let convolve (l1:float list) (l2:float list) = 
    List.fold_left (fun sum (a, b) -> sum +. a *. b) 0.0 (List.combine (List.rev l1) l2)
;;


let rec mc (cnt:int) (f: 'a -> 'a) (v: 'a) = 
    if cnt >= 1 then
	mc (cnt-1) f (f v)
    else
	v
;;

let successor (mcn: ('a -> 'a) -> 'a -> 'a) (f: 'a -> 'a) (v: 'a) = 
    f(mcn f v)

let make_index (index: (int * string list) list) = 
    let rec make_list n v = 
	if n=0 then []
	else v::(make_list (n-1) v)
    in
    let compress (lst:(string*int) list) = 
	let rec com (lst:(string*int) list) (acc1word:string) acc1 acc2 = 
	    match lst with
		[] -> 
		    (acc1word, List.rev acc1)::acc2
	      | (word,page)::xs ->
		    match acc1 with
			[] -> com xs word [page] acc2
		      | _ -> 
			    if compare word acc1word = 0 then
				com xs acc1word (page::acc1) acc2
			    else
				com xs word [page] ( (acc1word, List.rev acc1)::acc2 )
	in
	    com lst "" [] []
    in
    let new_list = 
	List.concat (
	    List.map (fun l -> 
			  let n, ss = l in 
			  let len = List.length ss in
			  let nlst = List.combine ss (make_list len n) in
			      nlst
		     ) index )
    in
    let sorted = List.sort compare new_list
    in
	List.rev (compress sorted)



let random_sublist (lst:'a list) k = 
    let n = List.length lst in 
    let perm = Array.init n (fun i -> i) in
	for i=1 to n-1 do 
	    let j = Random.int i in
	    let tmp = perm.(j) in
		perm.(j) <- perm.(i);
		perm.(i) <- tmp;
	done;
	for i=0 to n-1 do 
	    print_int perm.(i)
	done;
	let perm2 = Array.sub perm 0 k in
	    Array.sort compare perm2;
	    Array.to_list (Array.init (Array.length perm2) 
			       (fun i -> List.nth lst perm2.(i)))
	
let (|>) x f = f x		

[1;3;4]
|> List.map (fun i->i*i)
|> List.length



			  
